﻿/**************************************************************
 * Copyright gt1987. All rights reserved.
 * 
 * Author: guitao(guitao@eastmoney.com) 
 * Create Date: 2020/5/12 13:31:03
 * Description: TaskSchedulerManager
 *          
 * Revision History:
 *      Date         Author               Description
 *              
***************************************************************/

using gt.TaskScheduler.Core.Components;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace gt.TaskScheduler.Core.Impl
{
    public class TaskSchedulerManager : ITaskSchedulerMananger
    {
        private IDistributeFeature _distribute;
        private IKeyBuilder _keyBuilder;

        public TaskSchedulerManager(IDistributeFeature distribute, IKeyBuilder keyBuilder)
        {
            _distribute = distribute;
            _keyBuilder = keyBuilder;
        }
        /// <summary>
        /// 检查集群所有节点是否完成
        /// </summary>
        /// <returns></returns>
        public bool CheckAllMembersFinished()
        {
            var key = _keyBuilder.GetMemberCollectionKey();
            var dic = _distribute.GetAllData(key);
            if (dic == null || dic.Count == 0) return true;

            bool allFinished = true;
            foreach (var member in dic)
            {
                if (member.Value != ((int)MemberStatus.Stop).ToString())
                {
                    allFinished = false;
                    break;
                }
            }
            return allFinished;
        }
        /// <summary>
        /// 检查任务调度集群是否在运行中
        /// </summary>
        /// <returns></returns>
        public bool CheckTaskSchedulerRunning()
        {
            var key = _keyBuilder.GetMemberLeaderKey();
            var dic = _distribute.GetAllData(key);
            if (dic != null && dic.Count != 0)
            {
                var kv = dic.First();
                if (kv.Value == ((int)TaskSchedulerStatus.Run).ToString())
                {
                    return true;
                }
            }
            return false;
        }
        /// <summary>
        /// 检查任务调度集群是否可以重新开始
        /// </summary>
        /// <returns></returns>
        public bool CheckTaskSchedulerCanStart()
        {
            var key = _keyBuilder.GetMemberLeaderKey();
            var dic = _distribute.GetAllData(key);
            if (dic == null || dic.Count == 0) return true;
            if (dic != null && dic.Count != 0)
            {
                var kv = dic.First();
                //确认状态已经结束
                if (kv.Value == ((int)TaskSchedulerStatus.Stop).ToString())
                {
                    return true;
                }
            }
            return false;
        }
        /// <summary>
        /// 拉取TaskName
        /// </summary>
        /// <returns>返回 null 则表示队列已消费完</returns>
        public string DequeueTaskName()
        {
            var taskQueueKey = _keyBuilder.GetTaskQueueKey();
            return _distribute.Dequeue(taskQueueKey);
        }
        /// <summary>
        /// 初始化任务列表
        /// </summary>
        /// <returns></returns>
        public void InitTaskQueue(List<string> taskNames)
        {
            if (taskNames == null || taskNames.Count == 0) return;
            var key = _keyBuilder.GetTaskQueueKey();
            //先清空旧数据以防脏数据存在的话
            _distribute.DeleteData(key);
            _distribute.Enqueue(key, taskNames);
        }
        /// <summary>
        /// 标记节点状态
        /// </summary>
        /// <param name="memberName">节点名称</param>
        /// <param name="status">状态</param>
        public void MarkMemberStatus(string memberName, MemberStatus status)
        {
            var key = _keyBuilder.GetMemberCollectionKey();
            _distribute.SetData(key, memberName, ((int)status).ToString());
        }
        /// <summary>
        /// 标记任务调度集群状态
        /// </summary>
        /// <param name="memberName">节点名称</param>
        /// <param name="status">状态</param>
        public void MarkTaskSchedulerStatus(string memberName, TaskSchedulerStatus status)
        {
            var key = _keyBuilder.GetMemberLeaderKey();
            _distribute.SetData(key, memberName, ((int)status).ToString());
        }
        /// <summary>
        /// 注册集群Leader
        /// </summary>
        public void RegisterLeader(string memberName)
        {
            var key = _keyBuilder.GetMemberLeaderKey();
            //del first
            _distribute.DeleteData(key);
            MarkTaskSchedulerStatus(memberName, TaskSchedulerStatus.Start);
        }
        /// <summary>
        /// 节点member注册
        /// </summary>
        public void RegisterMember(string memberName)
        {
            MarkMemberStatus(memberName, MemberStatus.Register);
        }
    }
}
